`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company: Peking University
// Author: WANG, Pei 
// 
// Create Date:    18:35:08 11/11/2011 
// Module Name:    serial_in 
//////////////////////////////////////////////////////////////////////////////////
module serial_in(
    input[31:0]    din,
    input          clk,
    input          rst,
    output[2047:0] dout,
    output[5:0]    oaddr,
    output[1:0]    iwen,
    output         busy
    );

reg[2047:0] out_buff;
reg[1:0]    iwen_local;
reg         is_receiving;

assign iwen = iwen_local;
assign dout = out_buff;
assign busy = is_receiving;


reg[13:0]   index;
reg[5:0]    addr_select;

wire[5:0] out_buff_select;

assign out_buff_select = index[5:0];

assign oaddr = addr_select;

always @(posedge clk) begin
    if(rst) begin
        out_buff <= 0;
    end
    else begin 
        case(out_buff_select[5:0])
         0: out_buff[  31:   0] <= din;
         1: out_buff[  63:  32] <= din;
         2: out_buff[  95:  64] <= din;
         3: out_buff[ 127:  96] <= din;
         4: out_buff[ 159: 128] <= din;
         5: out_buff[ 191: 160] <= din;
         6: out_buff[ 223: 192] <= din;
         7: out_buff[ 255: 224] <= din;
         8: out_buff[ 287: 256] <= din;
         9: out_buff[ 319: 288] <= din;
        10: out_buff[ 351: 320] <= din;
        11: out_buff[ 383: 352] <= din;
        12: out_buff[ 415: 384] <= din;
        13: out_buff[ 447: 416] <= din;
        14: out_buff[ 479: 448] <= din;
        15: out_buff[ 511: 480] <= din;
        16: out_buff[ 543: 512] <= din;
        17: out_buff[ 575: 544] <= din;
        18: out_buff[ 607: 576] <= din;
        19: out_buff[ 639: 608] <= din;
        20: out_buff[ 671: 640] <= din;
        21: out_buff[ 703: 672] <= din;
        22: out_buff[ 735: 704] <= din;
        23: out_buff[ 767: 736] <= din;
        24: out_buff[ 799: 768] <= din;
        25: out_buff[ 831: 800] <= din;
        26: out_buff[ 863: 832] <= din;
        27: out_buff[ 895: 864] <= din;
        28: out_buff[ 927: 896] <= din;
        29: out_buff[ 959: 928] <= din;
        30: out_buff[ 991: 960] <= din;
        31: out_buff[1023: 992] <= din;
        32: out_buff[1055:1024] <= din;
        33: out_buff[1087:1056] <= din;
        34: out_buff[1119:1088] <= din;
        35: out_buff[1151:1120] <= din;
        36: out_buff[1183:1152] <= din;
        37: out_buff[1215:1184] <= din;
        38: out_buff[1247:1216] <= din;
        39: out_buff[1279:1248] <= din;
        40: out_buff[1311:1280] <= din;
        41: out_buff[1343:1312] <= din;
        42: out_buff[1375:1344] <= din;
        43: out_buff[1407:1376] <= din;
        44: out_buff[1439:1408] <= din;
        45: out_buff[1471:1440] <= din;
        46: out_buff[1503:1472] <= din;
        47: out_buff[1535:1504] <= din;
        48: out_buff[1567:1536] <= din;
        49: out_buff[1599:1568] <= din;
        50: out_buff[1631:1600] <= din;
        51: out_buff[1663:1632] <= din;
        52: out_buff[1695:1664] <= din;
        53: out_buff[1727:1696] <= din;
        54: out_buff[1759:1728] <= din;
        55: out_buff[1791:1760] <= din;
        56: out_buff[1823:1792] <= din;
        57: out_buff[1855:1824] <= din;
        58: out_buff[1887:1856] <= din;
        59: out_buff[1919:1888] <= din;
        60: out_buff[1951:1920] <= din;
        61: out_buff[1983:1952] <= din;
        62: out_buff[2015:1984] <= din;
        63: out_buff[2047:2016] <= din;
        endcase
    end
end

always @(posedge clk) begin
    if(!is_receiving | (|index[5:0]) == 0)
        iwen_local <= {index[12], ~index[12]};
    else
        iwen_local <= 2'b00;
end

always @(posedge clk) begin
    if(rst) begin
        index <= 0;
        is_receiving <= 1;
        addr_select <= 0;
    end
    else if(is_receiving) begin
        index <= index + 1;
        addr_select <= index[11:6];
        is_receiving <= ~index[13];
    end
    else
        is_receiving <= 0;
end

endmodule
